package com.atlassian.jira.server;

import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.jaxrs.JAXRSBindingFactory;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.log4j.Logger;

import com.atlassian.jira.resource.DefaultGroup;
import com.atlassian.jira.resource.DefaultUser;
import com.atlassian.jira.service.DefaultUserAndGroupService;

/**
 * This class instantiates the CXF REST server and it holds no knowledge of JIRA
 * (see <tt>JiraRestServerWrapper</tt>).
 * 
 * @author yclian
 * 
 */
public class DefaultJiraRestServer implements JiraRestServer {

	private static final Logger LOGGER = Logger.getLogger(DefaultJiraRestServer.class);
	private JAXRSServerFactoryBean jaxrsServerFactoryBean;

	public DefaultJiraRestServer() {
	}

	public synchronized JAXRSServerFactoryBean getJaxrsServerFactoryBean() {
		return jaxrsServerFactoryBean;
	}

	public synchronized void setJaxrsServerFactoryBean(JAXRSServerFactoryBean jaxrsServerFactoryBean) {
		this.jaxrsServerFactoryBean = jaxrsServerFactoryBean;
	}

	public synchronized void start(Map<Properties, String> properties) {

		if (this.jaxrsServerFactoryBean == null) {
			this.jaxrsServerFactoryBean = new JAXRSServerFactoryBean();
		}

		this.jaxrsServerFactoryBean.setResourceClasses(DefaultUser.class, DefaultGroup.class);
		this.jaxrsServerFactoryBean.setBindingId(JAXRSBindingFactory.JAXRS_BINDING_ID);
		this.jaxrsServerFactoryBean.setServiceBeans(new DefaultUserAndGroupService());

		// ADDRESS
		this.jaxrsServerFactoryBean.setAddress(properties.get(JiraRestServer.Properties.ADDRESS));

		// IN_INTERCEPTORS
		String inInterceptorsPropertyValue = StringUtils.defaultIfEmpty(properties.get(JiraRestServer.Properties.IN_INTERCEPTORS), "");
		String[] inInterceptorsValues = inInterceptorsPropertyValue.split(",");
		for (int i = 0; i < inInterceptorsValues.length; i++) {
			String inInterceptorValue = inInterceptorsValues[i];
			this.jaxrsServerFactoryBean.getInInterceptors().add(this.getInterceptorFromClassName(inInterceptorValue));
		}

		// OUT_INTERCEPTORS
		String outInterceptorsPropertyValue = StringUtils.defaultIfEmpty(properties.get(JiraRestServer.Properties.OUT_INTERCEPTORS), "");
		String[] outInterceptorsValues = outInterceptorsPropertyValue.split(",");
		for (int i = 0; i < outInterceptorsValues.length; i++) {
			String outInterceptorValue = outInterceptorsValues[i];
			this.jaxrsServerFactoryBean.getOutInterceptors().add(this.getInterceptorFromClassName(outInterceptorValue));
		}

		this.jaxrsServerFactoryBean.create();
	}

	public void stop() {
	}

	private Interceptor<?> getInterceptorFromClassName(String className) {

		assert (className != null);

		try {
			return (Interceptor<?>) Class.forName(className).newInstance();
		} catch (Exception e) {
			LOGGER.warn("Could not load and instantiate class " + className);
			return null;
		}
	}
}
